package cn.com.lms.business.core.util;

import cn.com.lms.business.learning.persistence.entity.vo.LearningViewVo;
import com.bnzj.core.persistence.entity.BaseEntity;
import com.bnzj.cloud.business.core.persistence.entity.SysUser;

import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyDescriptor;
import java.text.DecimalFormat;
import java.util.*;

@Slf4j
public class FBUtils {

    public static String formatUserName(int userName) {
        return userName >= 100000 ? userName + "" : new DecimalFormat("00000").format(userName);
    }

    /**
     * 把List<Map<K,V>>转换为List<T>
     *
     * @param listMap
     * @param resultClass
     * @return
     * @throws Exception
     */
    public static <T> List<T> convertListMapToListBean(List<Map<String, Object>> listMap, Class<T> resultClass) throws Exception {
        List<T> beanList = new ArrayList<T>();
        for (int i = 0, n = listMap.size(); i < n; i++) {
            Map<String, Object> map = listMap.get(i);
            Object obj = resultClass.newInstance();
            ConvertUtils.register(new DateConverter(null), java.util.Date.class);
            BeanUtils.populate(obj, map);
            beanList.add((T) obj);
        }
        return beanList;
    }


    /**
     * 把List<T>转换为List<Map<K,V>>
     *
     * @param listMap
     * @param resultClass
     * @return
     * @throws Exception
     */
    public static List<Map<String, Object>> convertListBeanToListMap(List<?> beanList) throws Exception {
        List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
        for (int i = 0, n = beanList.size(); i < n; i++) {
            Object bean = beanList.get(i);
            PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(bean);
            Map<String, Object> map = new HashMap<String, Object>();
            for (PropertyDescriptor descriptor : descriptors) {
                final String name = descriptor.getName();
                Object value = PropertyUtils.getProperty(bean, name);
                map.put(name, value);
            }
            mapList.add(map);
        }
        return mapList;
    }

    /**
     * 获取对象的属性值为空的属性名称
     *
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null)
                emptyNames.add(pd.getName());
        }
        return emptyNames.toArray(new String[emptyNames.size()]);
    }

    public static Object getProperty(Object bean, String fieldName) {
        try {
            return PropertyUtils.getProperty(bean, fieldName);
        } catch (Exception e) {
            log.error("类{}找不到{}属性", bean.getClass().getName(), fieldName);
            return null;
        }
    }

    public static <T extends BaseEntity> T saveBefore(T entity, SysUser user) {
        if (user == null) {
            log.warn("user is null");
            return entity;
        }
        if (entity.getId() == null) {
            entity.setCreator(user.getAccount());
            entity.setCreatorName(user.getCname());
            entity.setModifyBy(user.getAccount());
            entity.setModifyName(user.getCname());
            entity.setModifyTime(new Date());
            entity.setCreateTime(new Date());
        }
        if (entity.getId() != null) {
            entity.setModifyBy(user.getAccount());
            entity.setModifyName(user.getCname());
            entity.setModifyTime(new Date());
        }
        return entity;
    }

    /**
     * HikariDataSource优化配置
     *
     * @param hikariDataSource
     * @return
     */
    public static HikariDataSource configHikariDataSource(HikariDataSource hikariDataSource) {
        hikariDataSource.addDataSourceProperty("cachePrepStmts", true);
        hikariDataSource.addDataSourceProperty("prepStmtCacheSize", 250);
        hikariDataSource.addDataSourceProperty("prepStmtCacheSqlLimit", 2560);
        hikariDataSource.addDataSourceProperty("useServerPrepStmts", true);
        hikariDataSource.addDataSourceProperty("useLocalSessionState", true);
        hikariDataSource.addDataSourceProperty("rewriteBatchedStatements", true);
        hikariDataSource.addDataSourceProperty("cacheResultSetMetadata", true);
        hikariDataSource.addDataSourceProperty("cacheServerConfiguration", true);
        hikariDataSource.addDataSourceProperty("elideSetAutoCommits", true);
        hikariDataSource.addDataSourceProperty("maintainTimeStats", false);
        return hikariDataSource;
    }

    /**
     * getStrSuffix:获取字符串后缀. <br/>
     *
     * @param str
     * @return .+后缀名: 如.txt
     * @since JDK 1.8
     */
    public static String getStrSuffix(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        return str.substring(str.lastIndexOf("."), str.length());
    }

    /**
     * 前端select多选框，生成List集合存储传递的数据
     *
     * @param request
     * @param multipleParamName select标签的name
     * @return
     */
    public static List<String> getMultipleParam(HttpServletRequest request, String multipleParamName) {
        String multipleParam = request.getParameter(multipleParamName);
        List<String> customerStageList = null;
        if (multipleParam == null) {
            String[] customerStages = request.getParameterValues(multipleParamName + "[]");
            if (customerStages != null) {
                customerStageList = Arrays.asList(customerStages);
            }
        } else {
            customerStageList = new ArrayList<String>();
            customerStageList.add(multipleParam);
        }
        return customerStageList;
    }

    public static String getKey(Map<String, Object> map, String value) {
        String key = "";
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                key = entry.getKey();
            }
        }
        return key;
    }
}
